package com.gosling.cloudspace.tools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;

import java.util.List;
import java.util.Map;


//@Component
//@Slf4j
public class JsonParseTool {

    /***
     * 提取json里面的数组、集合、或者JSON对象
     * jsonFieldLayer 设置JSON数据的提取路径范围 [格式是分层级用分割符进行标注]
     * 注意：jsonFieldLayer的最终层级只能传数组、集合、或者JSON对象
     *
     * @param json
     * @param jsonFieldLayer 设置JSON数据的提取路径范围 [格式是分层级用分割符进行标注]
     * //@param jsonField      在提取路径下的多个值
     * @return
     */
    public static List<JSONObject> JsonParser(String json, String jsonFieldLayer) {
        List<JSONObject> list = Lists.newLinkedList();
        // 设定分割符
        String[] splitArray = jsonFieldLayer.split("->");
        try {
            if (json.startsWith("[") && json.endsWith("]")) {
                JSONArray nextNodeArray = JSON.parseArray(json);
                for (int nodeIndex = 0; nodeIndex < nextNodeArray.size(); nodeIndex++) {
                    JSONObject childNodeObj = nextNodeArray.getJSONObject(nodeIndex);
                    // 递归数据提取
                    recursiveAssignment(splitArray[0], 0, splitArray, childNodeObj, list);
                }
            } else {
                // JSON本身即对象
                recursiveAssignment(splitArray[0], 0, splitArray, JSON.parseObject(json), list);
            }
        } catch (Exception e) {
            e.printStackTrace();
            list.add(new JSONObject(1));
        }
        return list;
    }

    /***
     * 递归体
     *
     * @param childLayer
     * @param index
     * @param layerArray
     * @param resultMap
     * @param outputList
     */
    private static void recursiveAssignment(String childLayer, int index, String[] layerArray, Map<String, Object> resultMap, List<JSONObject> outputList) {
        String childNode = resultMap.get(childLayer).toString();
        if (childLayer.equals(layerArray[layerArray.length - 1])) {
            // 获取最底层数据节点，以明确最终所需要返回的最小对象颗粒
            assemblyNode(childNode, outputList, layerArray);
        } else {
            // 计算下一个索引位
            int nextindex = index + 1;
            // 向下层进行数据节点计算
            String nextLayer = layerArray[nextindex];
            if (childNode.startsWith("[") && childNode.endsWith("]")) {
                JSONArray nextNodeArray = JSON.parseArray(childNode);
                for (int nodeIndex = 0; nodeIndex < nextNodeArray.size(); nodeIndex++) {
                    JSONObject childNodeObj = nextNodeArray.getJSONObject(nodeIndex);
                    recursiveAssignment(nextLayer, nextindex, layerArray, childNodeObj, outputList);
                }
            } else {
                JSONObject childJsonObject = JSON.parseObject(childNode);
                recursiveAssignment(nextLayer, nextindex, layerArray, childJsonObject, outputList);
            }
        }
    }

    /***
     * 获取最底层数据节点，以明确最终所需要返回的最小对象颗粒
     * @param nextNode
     * @param outputList
     */
    private static void assemblyNode(String nextNode, List<JSONObject> outputList, String[] layerArray) {
        if (nextNode.startsWith("[") && nextNode.endsWith("]")) {
            //判断数据节点是否是数组
            JSONArray nextNodeArray = JSON.parseArray(nextNode);
            for (int nodeIndex = 0; nodeIndex < nextNodeArray.size(); nodeIndex++) {
                JSONObject childNodeObj = nextNodeArray.getJSONObject(nodeIndex);
                outputList.add(childNodeObj);
            }
        } else if (nextNode.startsWith("{") && nextNode.endsWith("}")){
            //判断数据节点是否是对象
            JSONObject childNodeObj = JSON.parseObject(nextNode);
            outputList.add(childNodeObj);
        } else {

        }
    }

    public static void main(String[] args) {
        String json = "{\"request\":{\"head\":{\"reIssrId\":\"Z2014751000013\",\"issrId\":\"G4000311000018\",\"msgSndTm\":\"20210817143523\",\"msgTp\":\"uops.020.000.01\",\"reserve\":{\"key1\":\"123\",\"key2\":\"456\"},\"msgId\":\"plat7bba5448541f996d180e1a8bffdf4\",\"drctn\":\"02\",\"signSN\":\"4032069135\"},\"body\":{\"cntList\":[{\"bizChan\":\"01\",\"bizTypeList\":[\"0000\"],\"infoNo\":\"39920320200228141657\",\"opList\":[{\"payOp\":\"02\"}],\"idcList\":\"\",\"cntNo\":\"1\",\"content\":\"\",\"instId\":\"G4000311000018\",\"toPayment\":\"1\",\"infoType\":\"03\",\"idcList2\":\"\",\"toBank\":\"1\",\"startTime\":\"20210818143521\",\"endTime\":\"20210819143521\",\"instName\":\"网联清算有限公司\",\"accType\":[\"00\"],\"overOpera\":\"\",\"contacts\":\"\",\"desc\":\"\",\"status\":\"1\"}],\"cntSumNo\":\"1\"}}}";
        List<JSONObject> reserveList = JsonParseTool.JsonParser(json, "request->head->reserve");
        System.out.println("reserveList:" + reserveList.toString());

        List<JSONObject> cntList = JsonParseTool.JsonParser(json, "request->body->cntList");
        System.out.println("cntList:" + cntList.toString());

        List<JSONObject> msgId = JsonParseTool.JsonParser(json, "request->head->1");
        System.out.println("msgId:" + msgId.toString());
    }
}